/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.model.codes;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.zhiqim.kernel.constants.CodeConstants;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Hexs;

/**
 * MD5编码，调用JDK的MD5编码
 * 
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class MD5 implements CodeConstants
{
    /**
     * MD5 编码，UTF8
     * 
     * @param src 源串
     * @return 目标串
     */
    public static String encodeUTF8(String src)
    {
        return encode(src, _UTF_8_C_);
    }
    
    /**
     * MD5编码，指定encding
     * 
     * @param src       源串
     * @param encoding  编码
     * @return          目标串
     */
    public static String encode(String src, String encoding)
    {
        byte[] destBytes = encodeByte(src, encoding);
        return Hexs.toHexString(destBytes);
    }
    
    /**
     * MD5编码，指定encding
     * 
     * @param src       源串
     * @param charset   字符集
     * @return          目标串
     */
    public static String encode(String src, Charset charset)
    {
        byte[] destBytes = encodeByte(src, charset);
        return Hexs.toHexString(destBytes);
    }
    
    /**
     * MD5编码，指定encding
     * 
     * @param src   源字节数组
     * @return      目标字节数组
     */
    public static String encode(byte[] src)
    {
        byte[] destBytes = encodeByte(src);
        return Hexs.toHexString(destBytes);
    }
    
    /**
     * MD5编码,返回byte数组
     * 
     * @param src       源串
     * @param encoding  编码
     * @return          目标字节数组
     */
    public static byte[] encodeByte(String src, String encoding)
    {
        Asserts.notNull(src, _SRC_);
        Asserts.notNull(encoding, _ENCODING_);
        
        try
        {
            return encodeByte(src.getBytes(encoding));
        }
        catch (UnsupportedEncodingException e)
        {
            throw Asserts.exception("非法的编码");
        }
    }
    
    /**
     * MD5编码,返回byte数组
     * 
     * @param src       源串
     * @param charset   字符集
     * @return          目标字节数组
     */
    public static byte[] encodeByte(String src, Charset charset)
    {
        Asserts.notNull(src, _SRC_);
        Asserts.notNull(charset, _CHARSET_);
        
        return encodeByte(src.getBytes(charset));
    }

    /**
     * MD5编码,返回byte数组
     * 
     * @param src   源字节数组
     * @return      目标字节数组
     */
    public static byte[] encodeByte(byte[] src)
    {
        Asserts.notNull(src, _SRC_);
        return getInstance().digest(src);
    }
    
    /**
     * 获取MD5消息摘要实例
     * 
     * @return  MD5消息摘要实例
     */
    public static MessageDigest getInstance()
    {
        try
        {
            return MessageDigest.getInstance(_MD5_);
        }
        catch (NoSuchAlgorithmException e)
        {
            throw Asserts.exception("JDK不支持["+_MD5_+"]算法");
        }
    }
}
